home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr25
/
memsz130.zip
/
MEMSIZE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-14
|
84KB
|
2,564 lines
/************************************************************** MEMSIZE.C
* *
* System Resources Monitor *
* *
* Revision 1.30 (07/06/92) *
* *
* (C) Copyright 1991-1992 by Richard W. Papo. *
* *
* This is 'FreeWare'. As such, it may be copied and distributed *
* freely. If you want to use part of it in your own program, please *
* give credit where credit is due. If you want to change the *
* program, please refer the change request to me or send me the *
* modified source code. I can be reached at CompuServe 72607,3111 or *
* through the Magnum BBS for OS/2 (ID 2370). *
* *
************************************************************************/
#define INCL_DOS
#define INCL_WIN
#define INCL_GPI
#include <os2.h>
#include <direct.h>
#include <process.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys\types.h>
#include <sys\stat.h>
#include "object.h"
#include "about.h"
#include "memsize.h"
#define TRUE 1
#define FALSE 0
#define NOT !
#define OR ||
#define AND &&
#define PROGRAM_NAME "MEMSIZE"
#define ITEM_MEMORYFREE 0
#define ITEM_SWAPFILESIZE 1
#define ITEM_SWAPDISKFREE 2
#define ITEM_SPOOLFILESIZE 3
#define ITEM_CPULOAD 4
/************************************************************************
* Type Definitions *
************************************************************************/
typedef struct // Data structure for item to be monitored.
{
PCHAR Name ; // Text for item's profile name.
BOOL Flag ; // Flag: Show this item at this time?
PCHAR Label ; // Text to display on left part of line.
ULONG Value ; // Value to display on right part of line.
PCHAR MenuOption ; // Text to display in system menu.
USHORT MenuId ; // ID for use in system menu.
ULONG (*NewValue) // Function to determine new value.
(void*,USHORT) ;
USHORT Parm ; // Parameter to pass to NewValue function.
USHORT Divisor ; // Amount to divide value by before display.
CHAR Suffix ; // Character to place after value.
}
ITEM ;
typedef struct // Data structure for Timing Thread.
{
TID tid ;
HWND hwndClient ;
ULONG *Count ;
}
TIMING_PARMS ;
typedef struct // Data structure for Counting Thread.
{
TID tid ;
ULONG *Count ;
}
COUNTING_PARMS ;
typedef struct // Data structure for Calibration Thread.
{
ULONG Count ;
}
CALIBRATION_PARMS ;
typedef struct // Parameters saved to system.
{
ITEM *Items ; // Items to display.
int ItemCount ;
SWP Position ; // Window size & location.
BOOL fPosition ;
BOOL HideControls ; // User options.
CHAR FontNameSize [80] ; // Presentation Parameters
BOOL fFontNameSize ;
COLOR BackColor ;
BOOL fBackColor ;
COLOR TextColor ;
BOOL fTextColor ;
}
PROFILE ;
typedef struct // Data structure for window.
{
ULONG MaxCount ;
ULONG Counter ;
ULONG NewLoad ;
PROFILE Profile ;
HWND hwndTitleBar ;
HWND hwndSysMenu ;
HWND hwndMinMax ;
char SwapPath [_MAX_PATH] ;
int MinFree ;
char *SpoolPath ;
FONTMETRICS FontMetrics ;
TID TimingThread ;
TIMING_PARMS TimingParms ;
TID CountingThread ;
COUNTING_PARMS CountingParms ;
}
DATA ;
/************************************************************************
* Function Prototypes *
************************************************************************/
VOID main ( VOID ) ;
static METHODFUNCTION Create ;
static METHODFUNCTION Destroy ;
static METHODFUNCTION Size ;
static METHODFUNCTION SaveApplication ;
static METHODFUNCTION Timer ;
static METHODFUNCTION Paint ;
static METHODFUNCTION Command ;
static METHODFUNCTION ButtonDown ;
static METHODFUNCTION ButtonDblClick ;
static METHODFUNCTION PresParamChanged ;
static METHODFUNCTION Semaphore1 ;
static METHODFUNCTION QueryKeysHelp ;
static METHODFUNCTION HelpError ;
static METHODFUNCTION ExtHelpUndefined ;
static METHODFUNCTION HelpSubitemNotFound ;
static void GetProfile ( PROFILE *Profile ) ;
static void PutProfile ( PROFILE *Profile ) ;
static char *ScanSystemConfig ( char *Keyword ) ;
static void ResizeWindow ( HWND hwnd, PROFILE *Profile ) ;
static void HideControls
(
BOOL fHide,
HWND hwndFrame,
HWND hwndSysMenu,
HWND hwndTitleBar,
HWND hwndMinMax
) ;
static void Debug ( HWND hwnd, char *Message, ... ) ;
static ULONG CalibrateLoad ( void ) ;
static void _cdecl _far TimingThread ( TIMING_PARMS *Parms ) ;
static void _cdecl _far CountingThread ( COUNTING_PARMS *Parms ) ;
static void _cdecl _far CalibrationThread ( CALIBRATION_PARMS *Parms ) ;
static void UpdateWindow ( HWND hwnd, DATA *Data, BOOL All ) ;
static ULONG ComputeFreeMemory ( DATA *Data, USHORT Dummy ) ;
static ULONG ComputeSwapSize ( DATA *Data, USHORT Dummy ) ;
static ULONG ComputeSwapFree ( DATA *Data, USHORT Dummy ) ;
static ULONG ComputeSpoolSize ( DATA *Data, USHORT Dummy ) ;
static ULONG ComputeCpuLoad ( DATA *Data, USHORT Dummy ) ;
static ULONG ComputeDriveFree ( DATA *Data, USHORT Drive ) ;
/************************************************************************
* Global Definitions *
************************************************************************/
#define ID_MAIN 1
#define ID_TIMER 1
static HAB hAB ;
static HWND hwndHelp ;
static METHOD Methods [] =
{
{ WM_CREATE, Create },
{ WM_DESTROY, Destroy },
{ WM_SIZE, Size },
{ WM_MOVE, Size },
{ WM_SAVEAPPLICATION, SaveApplication },
{ WM_TIMER, Timer },
{ WM_PAINT, Paint },
{ WM_COMMAND, Command },
{ WM_BUTTON1DOWN, ButtonDown },
{ WM_BUTTON2DOWN, ButtonDown },
{ WM_BUTTON1DBLCLK, ButtonDblClick },
{ WM_BUTTON2DBLCLK, ButtonDblClick },
{ WM_PRESPARAMCHANGED, PresParamChanged },
{ WM_SEM1, Semaphore1 },
{ HM_QUERY_KEYS_HELP, QueryKeysHelp },
{ HM_ERROR, HelpError },
{ HM_EXT_HELP_UNDEFINED, ExtHelpUndefined },
{ HM_HELPSUBITEM_NOT_FOUND, HelpSubitemNotFound }
} ;
static CLASS Class =
{
Methods,
sizeof(Methods)/sizeof(METHOD),
WinDefWindowProc,
sizeof(DATA),
0,
TRUE,
{
0,
FCF_TITLEBAR | FCF_SYSMENU | FCF_BORDER |
FCF_ICON | FCF_MINBUTTON | FCF_NOBYTEALIGN | FCF_ACCELTABLE,
0,
ID_MAIN
}
} ;
HELPINIT HelpInit =
{
sizeof ( HELPINIT ),
0L,
NULL,
MAKEP ( 0xFFFF, ID_MAIN ),
0,
0,
0,
0,
"\"System Resources\" Help Facility",
CMIC_HIDE_PANEL_ID,
"MEMSIZE.HLP"
} ;
/************************************************************************
* *
* Program Mainline *
* *
************************************************************************/
VOID main ( VOID )
{
/***********************************************************************
* Go execute the window object. *
***********************************************************************/
Object ( &hAB, NULL, CS_MOVENOTIFY, &HelpInit, &hwndHelp,
HWND_DESKTOP, ID_MAIN, &Class, "System Resources" ) ;
}
/************************************************************************
* *
* Initialize main window. *
* *
************************************************************************/
static MRESULT APIENTRY Create
(
HWND hwnd,
USHORT msg,
MPARAM mp1,
MPARAM mp2,
void *data
)
{
/***********************************************************************
* Declarations *
***********************************************************************/
static PCHAR szMenuText [] =
{
"Save Defaults\tF2",
"Reset Defaults",
"Hide Controls",
} ;
static MENUITEM MenuItems [] =
{
{ MIT_END, MIS_TEXT, 0, IDM_SAVE_APPLICATION, NULL, 0 },
{ MIT_END, MIS_TEXT, 0, IDM_RESET_DEFAULTS, NULL, 0 },
{ MIT_END, MIS_TEXT, 0, IDM_HIDE_CONTROLS, NULL, 0 }
} ;
static MENUITEM MenuSeparator =
{ MIT_END, MIS_SEPARATOR, 0, 0, NULL, 0 } ;
static MENUITEM MenuAbout =
{ MIT_END, MIS_TEXT, 0, IDM_ABOUT, NULL, 0 } ;
static MENUITEM MenuItem =
{ MIT_END, MIS_TEXT, 0, 0, NULL, 0 } ;
DATA *Data = (DATA *) data ;
HPS hPS ;
HWND hwndFrame ;
HWND hwndSysMenu ;
HWND hwndSysSubMenu ;
SHORT i ;
SHORT idSysMenu ;
MENUITEM miSysMenu ;
PID pid ;
ULONG Size ;
char *Swappath ;
SWCNTRL swctl ;
/***********************************************************************
* Get profile data. *
***********************************************************************/
GetProfile ( &Data->Profile ) ;
/***********************************************************************
* Get the control window handles. *
***********************************************************************/
hwndFrame = WinQueryWindow ( hwnd, QW_PARENT, FALSE ) ;
Data->hwndSysMenu = WinWindowFromID ( hwndFrame, FID_SYSMENU ) ;
Data->hwndTitleBar = WinWindowFromID ( hwndFrame, FID_TITLEBAR ) ;
Data->hwndMinMax = WinWindowFromID ( hwndFrame, FID_MINMAX ) ;
/***********************************************************************
* Add basic extensions to the system menu. *
***********************************************************************/
hwndSysMenu = WinWindowFromID ( WinQueryWindow ( hwnd, QW_PARENT, FALSE ), FID_SYSMENU ) ;
idSysMenu = SHORT1FROMMR ( WinSendMsg ( hwndSysMenu, MM_ITEMIDFROMPOSITION, NULL, NULL ) ) ;
WinSendMsg ( hwndSysMenu, MM_QUERYITEM, MPFROM2SHORT(idSysMenu,FALSE), MPFROMP(&miSysMenu) ) ;
hwndSysSubMenu = miSysMenu.hwndSubMenu ;
WinSendMsg ( hwndSysSubMenu, MM_INSERTITEM,
MPFROMP(&MenuSeparator), MPFROMP(NULL) ) ;
for ( i=0; i<sizeof(MenuItems)/sizeof(MenuItems[0]); i++ )
{
WinSendMsg ( hwndSysSubMenu, MM_INSERTITEM, MPFROMP(MenuItems+i), MPFROMP(szMenuText[i]) ) ;
}
/***********************************************************************
* Add display items as options to the system menu. *
***********************************************************************/
WinSendMsg ( hwndSysSubMenu, MM_INSERTITEM,
MPFROMP(&MenuSeparator), MPFROMP(NULL) ) ;
for ( i=0; i<Data->Profile.ItemCount; i++ )
{
ITEM *Item = & Data->Profile.Items [i] ;
MenuItem.id = Item->MenuId ;
WinSendMsg ( hwndSysSubMenu, MM_INSERTITEM,
MPFROMP(&MenuItem), MPFROMP(Item->MenuOption) ) ;
WinSendMsg ( Data->hwndSysMenu, MM_SETITEMATTR,
MPFROM2SHORT ( Item->MenuId, TRUE ),
MPFROM2SHORT ( MIA_CHECKED, Item->Flag ? MIA_CHECKED : FALSE ) ) ;
}
/***********************************************************************
* Add 'About' to the system menu. *
***********************************************************************/
WinSendMsg ( hwndSysSubMenu, MM_INSERTITEM,
MPFROMP(&MenuSeparator), MPFROMP(NULL) ) ;
WinSendMsg ( hwndSysSubMenu, MM_INSERTITEM,
MPFROMP(&MenuAbout), MPFROMP("About...") ) ;
/***********************************************************************
* Start up a one-second timer. Return error if unable to do so. *
***********************************************************************/
if ( NOT WinStartTimer ( hAB, hwnd, ID_TIMER, 1000 ) )
{
WinMessageBox ( HWND_DESKTOP, hwnd, "ERROR: Too many clocks or timers",
"Memory Size", 0, MB_OK | MB_ICONEXCLAMATION ) ;
return ( MRFROMSHORT ( 1 ) ) ;
}
/***********************************************************************
* Get the SWAPPATH statement from CONFIG.SYS. *
***********************************************************************/
Swappath = ScanSystemConfig ( "SWAPPATH" ) ;
if ( Swappath == NULL )
{
Swappath = "C:\\OS2\\SYSTEM 0" ;
}
strupr ( Swappath ) ;
sscanf ( Swappath, "%s %i", Data->SwapPath, &Data->MinFree ) ;
/***********************************************************************
* Find out where the spool work directory is. *
***********************************************************************/
Data->SpoolPath = NULL ;
if ( PrfQueryProfileSize ( HINI_PROFILE, "PM_SPOOLER", "DIR", &Size ) )
{
Data->SpoolPath = malloc ( (int)Size ) ;
if ( Data->SpoolPath )
{
if ( PrfQueryProfileData ( HINI_PROFILE, "PM_SPOOLER", "DIR", Data->SpoolPath, &Size ) )
{
BYTE *p ;
p = strchr ( Data->SpoolPath, ';' ) ;
if ( p )
{
*p = 0 ;
}
}
else
{
free ( Data->SpoolPath ) ;
Data->SpoolPath = FALSE ;
}
}
}
/***********************************************************************
* Calibrate the load meter. *
***********************************************************************/
Data->MaxCount = CalibrateLoad ( ) ;
Data->TimingParms.hwndClient = hwnd ;
Data->TimingParms.Count = & Data->Counter ;
Data->TimingThread = _beginthread ( TimingThread,
NULL, 4000, &Data->TimingParms ) ;
Data->CountingParms.Count = & Data->Counter ;
Data->CountingThread = _beginthread ( CountingThread,
NULL, 4000, &Data->CountingParms ) ;
/***********************************************************************
* If not showing CPU load, suspend those threads. *
***********************************************************************/
if ( NOT Data->Profile.Items[ITEM_CPULOAD].Flag )
{
DosSuspendThread ( Data->TimingThread ) ;
DosSuspendThread ( Data->CountingThread ) ;
}
/***********************************************************************
* Add the program to the system task list. *
***********************************************************************/
WinQueryWindowProcess ( hwndFrame, &pid, NULL ) ;
swctl.hwnd = hwndFrame ;
swctl.hwndIcon = NULL ;
swctl.hprog = NULL ;
swctl.idProcess = pid ;
swctl.idSession = 0 ;
swctl.uchVisibility = SWL_VISIBLE ;
swctl.fbJump = SWL_JUMPABLE ;
strcpy ( swctl.szSwtitle, "System Resources" ) ;
WinAddSwitchEntry ( &swctl ) ;
/***********************************************************************
* Position & size the window. For some reason, we must move and size *
* the window to the saved position before applying the resizing *
* function as fine-tuning. Maybe the positioning request fails if *
* the window has no size? *
***********************************************************************/
WinSetWindowPos ( hwndFrame, NULL,
Data->Profile.Position.x, Data->Profile.Position.y,
Data->Profile.Position.cx, Data->Profile.Position.cy,
SWP_SIZE | SWP_MOVE ) ;
ResizeWindow ( hwnd, &Data->Profile ) ;
/***********************************************************************
* Hide the controls if so configured. *
***********************************************************************/
if ( Data->Profile.HideControls )
{
HideControls
(
TRUE,
hwndFrame,
Data->hwndSysMenu,
Data->hwndTitleBar,
Data->hwndMinMax
) ;
WinSendMsg ( Data->hwndSysMenu, MM_SETITEMATTR,
MPFROM2SHORT ( IDM_HIDE_CONTROLS, TRUE ),
MPFROM2SHORT ( MIA_CHECKED, Data->Profile.HideControls ? MIA_CHECKED : 0 ) ) ;
}
/***********************************************************************
* Get the saved presentation parameters and reinstate them. *
***********************************************************************/
if ( Data->Profile.fFontNameSize )
{
WinSetPresParam ( hwnd, PP_FONTNAMESIZE,
strlen(Data->Profile.FontNameSize)+1, Data->Profile.FontNameSize ) ;
}
if ( Data->Profile.fBackColor )
{
WinSetPresParam ( hwnd, PP_BACKGROUNDCOLOR,
sizeof(Data->Profile.BackColor), &Data->Profile.BackColor ) ;
}
if ( Data->Profile.fTextColor )
{
WinSetPresParam ( hwnd, PP_FOREGROUNDCOLOR,
sizeof(Data->Profile.TextColor), &Data->Profile.TextColor ) ;
}
hPS = WinGetPS ( hwnd ) ;
GpiQueryFontMetrics ( hPS, sizeof(Data->FontMetrics), &Data->FontMetrics ) ;
WinReleasePS ( hPS ) ;
/***********************************************************************
* Now that the window's in order, make it visible. *
***********************************************************************/
WinShowWindow ( hwndFrame, TRUE ) ;
/***********************************************************************
* Success? Return no error. *
***********************************************************************/
return ( 0 ) ;
hwnd = hwnd ;
msg = msg ;
mp1 = mp1 ;
mp2 = mp2 ;
}
/************************************************************************
* *
* Destroy main window. *
* *
************************************************************************/
static MRESULT APIENTRY Destroy
(
HWND hwnd,
USHORT msg,
MPARAM mp1,
MPARAM mp2,
void *data
)
{
/***********************************************************************
* Declarations *
***********************************************************************/
DATA *Data = (DATA *) data ;
/***********************************************************************
* Stop the timer. *
***********************************************************************/
WinStopTimer ( hAB, hwnd, ID_TIMER ) ;
/***********************************************************************
* Suspend the CPU load threads. *
***********************************************************************/
DosSuspendThread ( Data->TimingThread ) ;
DosSuspendThread ( Data->CountingThread ) ;
return ( 0 ) ;
hwnd = hwnd ;
msg = msg ;
mp1 = mp1 ;
mp2 = mp2 ;
}
/************************************************************************
* *
* Process window resize message. *
* *
************************************************************************/
static MRESULT APIENTRY Size
(
HWND hwnd,
USHORT msg,
MPARAM mp1,
MPARAM mp2,
void *data
)
{
/***********************************************************************
* Declarations *
***********************************************************************/
DATA *Data = (DATA *) data ;
HWND hwndFrame ;
SWP Position ;
/***********************************************************************
* Find out the window's new position and size. *
***********************************************************************/
hwndFrame = WinQueryWindow ( hwnd, QW_PARENT, FALSE ) ;
WinQueryWindowPos ( hwndFrame, &Position ) ;
if ( NOT ( Position.fs & SWP_MINIMIZE )
AND NOT ( Position.fs & SWP_MAXIMIZE ) )
{
Data->Profile.Position.x = Position.x ;
Data->Profile.Position.y = Position.y ;
Data->Profile.Position.cx = Position.cx ;
Data->Profile.Position.cy = Position.cy ;
}
Data->Profile.Position.fs = Position.fs ;
/***********************************************************************
* We're done. *
***********************************************************************/
return ( 0 ) ;
hwnd = hwnd ;
msg = msg ;
mp1 = mp1 ;
mp2 = mp2 ;
}
/************************************************************************
* *
* Process SAVE APPLICATION message. *
* *
************************************************************************/
static MRESULT APIENTRY SaveApplication
(
HWND hwnd,
USHORT msg,
MPARAM mp1,
MPARAM mp2,
void *data
)
{
/***********************************************************************
* Declarations *
***********************************************************************/
DATA *Data = (DATA *) data ;
/***********************************************************************
* Call function to put all profile data out to the system. *
***********************************************************************/
PutProfile ( &Data->Profile ) ;
/***********************************************************************
* We're done. Let the system complete default processing. *
***********************************************************************/
return ( WinDefWindowProc ( hwnd, msg, mp1, mp2 ) ) ;
hwnd = hwnd ;
msg = msg ;
mp1 = mp1 ;
mp2 = mp2 ;
}
/************************************************************************
* *
* Process timer message. *
* *
************************************************************************/
static MRESULT APIENTRY Timer
(
HWND hwnd,
USHORT msg,
MPARAM mp1,
MPARAM mp2,
void *data
)
{
/***********************************************************************
* Declarations *
***********************************************************************/
DATA *Data = (DATA *) data ;
/***********************************************************************
* Update the window and return. *
***********************************************************************/
UpdateWindow ( hwnd, Data, FALSE ) ;
return ( 0 ) ;
hwnd = hwnd ;
msg = msg ;
mp1 = mp1 ;
mp2 = mp2 ;
}
/************************************************************************
* *
* Repaint entire window. *
* *
************************************************************************/
static MRESULT APIENTRY Paint
(
HWND hwnd,
USHORT msg,
MPARAM mp1,
MPARAM mp2,
void *data
)
{
/***********************************************************************
* Declarations *
***********************************************************************/
DATA *Data = (DATA *) data ;
HPS hPS ;
RECTL Rectangle ;
/***********************************************************************
* Get presentation space and make it use RGB colors. *
***********************************************************************/
hPS = WinBeginPaint ( hwnd, NULL, NULL ) ;
GpiCreateLogColorTable ( hPS, LCOL_RESET, LCOLF_RGB, 0L, 0L, NULL ) ;
/***********************************************************************
* Clear the window. *
***********************************************************************/
WinQueryWindowRect ( hwnd, &Rectangle ) ;
GpiMove ( hPS, (PPOINTL) &Rectangle.xLeft ) ;
GpiSetColor ( hPS, Data->Profile.BackColor ) ;
GpiBox ( hPS, DRO_FILL, (PPOINTL) &Rectangle.xRight, 0L, 0L ) ;
/***********************************************************************
* Release presentation space. *
***********************************************************************/
WinEndPaint ( hPS ) ;
/***********************************************************************
* Update the window and return. *
***********************************************************************/
UpdateWindow ( hwnd, Data, TRUE ) ;
return ( 0 ) ;
hwnd = hwnd ;
msg = msg ;
mp1 = mp1 ;
mp2 = mp2 ;
}
/************************************************************************
* *
* Process commands received by Main Window *
* *
************************************************************************/
static MRESULT APIENTRY Command
(
HWND hwnd,
USHORT msg,
MPARAM mp1,
MPARAM mp2,
void *data
)
{
/***********************************************************************
* Local Declarations *
***********************************************************************/
DATA *Data = (DATA *) data ;
USHORT Command ;
short i ;
/***********************************************************************
* Process indicated command . . . *
***********************************************************************/
Command = SHORT1FROMMP ( mp1 ) ;
/***********************************************************************
* Process display item commands. *
***********************************************************************/
for ( i=0; i<Data->Profile.ItemCount; i++ )
{
ITEM *Item = & Data->Profile.Items [i] ;
if ( Command == Item->MenuId )
{
Item->Flag = Item->Flag ? FALSE : TRUE ;
WinSendMsg ( Data->hwndSysMenu, MM_SETITEMATTR,
MPFROM2SHORT ( Item->MenuId, TRUE ),
MPFROM2SHORT ( MIA_CHECKED, Item->Flag ? MIA_CHECKED : 0 ) ) ;
ResizeWindow ( hwnd, &Data->Profile ) ;
if ( i == ITEM_CPULOAD )
{
if ( Item->Flag )
{
DosResumeThread ( Data->TimingThread ) ;
DosResumeThread ( Data->CountingThread ) ;
}
else
{
DosSuspendThread ( Data->TimingThread ) ;
DosSuspendThread ( Data->CountingThread ) ;
}
}
return ( MRFROMSHORT ( 0 ) ) ;
}
}
/***********************************************************************
* Process fixed commands . . . *
***********************************************************************/
switch ( Command )
{
/*********************************************************************
* End the program. *
*********************************************************************/
case IDM_EXIT:
{
WinSendMsg ( hwnd, WM_CLOSE, 0L, 0L );
break ;
}
/*********************************************************************
* Save application defaults. *
*********************************************************************/
case IDM_SAVE_APPLICATION:
{
WinSendMsg ( hwnd, WM_SAVEAPPLICATION, 0L, 0L );
break ;
}
/*********************************************************************
* Reset application defaults. *
*********************************************************************/
case IDM_RESET_DEFAULTS:
{
PrfWriteProfileData ( HINI_USERPROFILE, PROGRAM_NAME, NULL, NULL, 0 ) ;
WinRemovePresParam ( hwnd, PP_FONTNAMESIZE ) ;
WinRemovePresParam ( hwnd, PP_FOREGROUNDCOLOR ) ;
WinRemovePresParam ( hwnd, PP_BACKGROUNDCOLOR ) ;
break ;
}
/*********************************************************************
* Hide Controls. *
*********************************************************************/
case IDM_HIDE_CONTROLS:
{
Data->Profile.HideControls = Data->Profile.HideControls ? FALSE : TRUE ;
HideControls
(
Data->Profile.HideControls,
WinQueryWindow ( hwnd, QW_PARENT, FALSE ),
Data->hwndSysMenu,
Data->hwndTitleBar,
Data->hwndMinMax
) ;
WinSendMsg ( Data->hwndSysMenu, MM_SETITEMATTR,
MPFROM2SHORT ( IDM_HIDE_CONTROLS, TRUE ),
MPFROM2SHORT ( MIA_CHECKED, Data->Profile.HideControls ? MIA_CHECKED : 0 ) ) ;
break ;
}
/*********************************************************************
* Display copyright information. *
*********************************************************************/
case IDM_ABOUT:
{
ABOUT_PARMS Parms ;
Parms.id = IDD_ABOUT ;
Parms.hwndHelp = hwndHelp ;
WinDlgBox ( HWND_DESKTOP, hwnd, AboutProcessor,
0, IDD_ABOUT, &Parms ) ;
break ;
}
/*********************************************************************
* None of the above? Beep a complaint. *
*********************************************************************/
default:
{
WinAlarm ( HWND_DESKTOP, WA_NOTE ) ;
break ;
}
}
return ( MRFROMSHORT ( 0 ) ) ;
hwnd = hwnd ; msg = msg ; mp1 = mp1 ; mp2 = mp2 ; data = data ;
}
/************************************************************************
* *
* Process Mouse Button being pressed. *
* *
************************************************************************/
static MRESULT APIENTRY ButtonDown
(
HWND hwnd,
USHORT msg,
MPARAM mp1,
MPARAM mp2,
void *data
)
{
/***********************************************************************
* Local Declarations *
***********************************************************************/
DATA *Data = (DATA *) data ;
HWND hwndFrame ;
SWP Position ;
TRACKINFO TrackInfo ;
/***********************************************************************
* Determine the new window position. *
***********************************************************************/
memset ( &TrackInfo, 0, sizeof(TrackInfo) ) ;
TrackInfo.cxBorder = 1 ;
TrackInfo.cyBorder = 1 ;
TrackInfo.cxGrid = 1 ;
TrackInfo.cyGrid = 1 ;
TrackInfo.cxKeyboard = 8 ;
TrackInfo.cyKeyboard = 8 ;
hwndFrame = WinQueryWindow ( hwnd, QW_PARENT, FALSE ) ;
WinQueryWindowPos ( hwndFrame, &Position ) ;
TrackInfo.rclTrack.xLeft = Position.x ;
TrackInfo.rclTrack.xRight = Position.x + Position.cx ;
TrackInfo.rclTrack.yBottom = Position.y ;
TrackInfo.rclTrack.yTop = Position.y + Position.cy ;
WinQueryWindowPos ( HWND_DESKTOP, &Position ) ;
TrackInfo.rclBoundary.xLeft = Position.x ;
TrackInfo.rclBoundary.xRight = Position.x + Position.cx ;
TrackInfo.rclBoundary.yBottom = Position.y ;
TrackInfo.rclBoundary.yTop = Position.y + Position.cy ;
TrackInfo.ptlMinTrackSize.x = 0 ;
TrackInfo.ptlMinTrackSize.y = 0 ;
TrackInfo.ptlMaxTrackSize.x = Position.cx ;
TrackInfo.ptlMaxTrackSize.y = Position.cy ;
TrackInfo.fs = TF_MOVE | TF_STANDARD | TF_ALLINBOUNDARY ;
if ( WinTrackRect ( HWND_DESKTOP, NULL, &TrackInfo ) )
{
WinSetWindowPos ( hwndFrame, NULL,
(SHORT) TrackInfo.rclTrack.xLeft,
(SHORT) TrackInfo.rclTrack.yBottom,
0, 0, SWP_MOVE ) ;
}
/***********************************************************************
* Return through the default processor, letting window activation *
* and other system functions occur. *
***********************************************************************/
return ( WinDefWindowProc ( hwnd, msg, mp1, mp2 ) ) ;
hwnd = hwnd ; msg = msg ; mp1 = mp1 ; mp2 = mp2 ; data = data ;
}
/************************************************************************
* *
* Process Mouse Button having been double-clicked. *
* *
************************************************************************/
static MRESULT APIENTRY ButtonDblClick
(
HWND hwnd,
USHORT msg,
MPARAM mp1,
MPARAM mp2,
void *data
)
{
/***********************************************************************
* Local Declarations *
***********************************************************************/
DATA *Data = (DATA *) data ;
/***********************************************************************
* Send message to self to stop hiding the controls. *
***********************************************************************/
WinPostMsg ( hwnd, WM_COMMAND,
MPFROM2SHORT ( IDM_HIDE_CONTROLS, 0 ),
MPFROM2SHORT ( CMDSRC_OTHER, TRUE ) ) ;
/***********************************************************************
* Return through the default processor, letting window activation *
* and other system functions occur. *
***********************************************************************/
return ( WinDefWindowProc ( hwnd, msg, mp1, mp2 ) ) ;
hwnd = hwnd ; msg = msg ; mp1 = mp1 ; mp2 = mp2 ; data = data ;
}
/************************************************************************
* *
* Process Presentation Parameter Changed notification. *
* *
************************************************************************/
static MRESULT APIENTRY PresParamChanged
(
HWND hwnd,
USHORT msg,
MPARAM mp1,
MPARAM mp2,
void *data
)
{
/***********************************************************************
* Local Declarations *
***********************************************************************/
DATA *Data = (DATA *) data ;
HPS hPS ;
ULONG ppid ;
/***********************************************************************
* Get the presentation parameter that changed. *
***********************************************************************/
switch ( LONGFROMMP(mp1) )
{
/*********************************************************************
* If font, note the fact that we now have a font to be saved as *
* part of the configuration. Get the font metrics and resize *
* the window appropriately. *
*********************************************************************/
case PP_FONTNAMESIZE:
{
if ( WinQueryPresParam ( hwnd, PP_FONTNAMESIZE, 0, &ppid,
sizeof(Data->Profile.FontNameSize), &Data->Profile.FontNameSize,
0 ) )
{
Data->Profile.fFontNameSize = TRUE ;
}
else
{
strcpy ( Data->Profile.FontNameSize, "" ) ;
Data->Profile.fFontNameSize = FALSE ;
PrfWriteProfileData ( HINI_USERPROFILE, PROGRAM_NAME, "FontNameSize", NULL, 0 ) ;
}
hPS = WinGetPS ( hwnd ) ;
GpiQueryFontMetrics ( hPS, sizeof(Data->FontMetrics), &Data->FontMetrics ) ;
WinReleasePS ( hPS ) ;
ResizeWindow ( hwnd, &Data->Profile ) ;
break ;
}
/*********************************************************************
* If background color, note the fact and repaint the window. *
*********************************************************************/
case PP_BACKGROUNDCOLOR:
{
if ( WinQueryPresParam ( hwnd, PP_BACKGROUNDCOLOR, 0, &ppid,
sizeof(Data->Profile.BackColor), &Data->Profile.BackColor, 0 ) )
{
Data->Profile.fBackColor = TRUE ;
WinInvalidateRect ( hwnd, NULL, TRUE ) ;
}
else
{
Data->Profile.BackColor = WinQuerySysColor ( HWND_DESKTOP, SYSCLR_WINDOW, 0L ) ;
Data->Profile.fBackColor = FALSE ;
PrfWriteProfileData ( HINI_USERPROFILE, PROGRAM_NAME, "BackgroundColor", NULL, 0 ) ;
}
break ;
}
/*********************************************************************
* If foreground color, note the fact and repaint the window. *
*********************************************************************/
case PP_FOREGROUNDCOLOR:
{
if ( WinQueryPresParam ( hwnd, PP_FOREGROUNDCOLOR, 0, &ppid,
sizeof(Data->Profile.TextColor), &Data->Profile.TextColor, 0 ) )
{
Data->Profile.fTextColor = TRUE ;
WinInvalidateRect ( hwnd, NULL, TRUE ) ;
}
else
{
Data->Profile.TextColor = WinQuerySysColor ( HWND_DESKTOP, SYSCLR_OUTPUTTEXT, 0L ) ;
Data->Profile.fTextColor = FALSE ;
PrfWriteProfileData ( HINI_USERPROFILE, PROGRAM_NAME, "ForegroundColor", NULL, 0 ) ;
}
break ;
}
}
/***********************************************************************
* Return through the default processor, letting window activation *
* and other system functions occur. *
***********************************************************************/
return ( WinDefWindowProc ( hwnd, msg, mp1, mp2 ) ) ;
hwnd = hwnd ; msg = msg ; mp1 = mp1 ; mp2 = mp2 ; data = data ;
}
/************************************************************************
* *
* Process Semaphore 1 notification. *
* *
************************************************************************/
static MRESULT APIENTRY Semaphore1
(
HWND hwnd,
USHORT msg,
MPARAM mp1,
MPARAM mp2,
void *data
)
{
/***********************************************************************
* Local Declarations *
***********************************************************************/
DATA *Data = (DATA *) data ;
ULONG Count ;
/***********************************************************************
* Compute CPU load. *
***********************************************************************/
Count = min ( LONGFROMMP(mp1), Data->MaxCount ) ;
Data->NewLoad = ( Count * 200 + 50 ) / Data->MaxCount ;
if ( Data->NewLoad > 100 )
Data->NewLoad = 0 ;
else
Data->NewLoad = 100 - Data->NewLoad ;
/***********************************************************************
* Return successful. *
***********************************************************************/
return ( 0 ) ;
hwnd = hwnd ; msg = msg ; mp1 = mp1 ; mp2 = mp2 ; data = data ;
}
/************************************************************************
* *
* Process Query for Keys Help resource id. *
* *
************************************************************************/
static MRESULT APIENTRY QueryKeysHelp
(
HWND hwnd,
USHORT msg,
MPARAM mp1,
MPARAM mp2,
void *data
)
{
/***********************************************************************
* Local Declarations *
***********************************************************************/
DATA *Data = (DATA *) data ;
/***********************************************************************
* Simply return the ID of the Keys Help panel. *
***********************************************************************/
return ( (MRESULT) IDM_KEYS_HELP ) ;
hwnd = hwnd ; msg = msg ; mp1 = mp1 ; mp2 = mp2 ; data = data ;
}
/************************************************************************
* *
* Process Help Manager Error *
* *
************************************************************************/
static MRESULT APIENTRY HelpError
(
HWND hwnd,
USHORT msg,
MPARAM mp1,
MPARAM mp2,
void *data
)
{
/***********************************************************************
* Local Declarations *
***********************************************************************/
static struct
{
ULONG Error ;
PSZ Message ;
}
HelpErrors [] =
{
{ HMERR_NO_FRAME_WND_IN_CHAIN, "No frame window in chain." },
{ HMERR_INVALID_ASSOC_APP_WND, "Invalid window handle associated." },
{ HMERR_INVALID_ASSOC_HELP_INST, "Invalid help instance associated." },
{ HMERR_INVALID_DESTROY_HELP_INST, "Invalid window handle to deassociate." },
{ HMERR_NO_HELP_INST_IN_CHAIN, "No help instance in window chain." },
{ HMERR_INVALID_HELP_INSTANCE_HDL, "Invalid help instance handle." },
{ HMERR_INVALID_QUERY_APP_WND, "Invalid application window handle in query." },
{ HMERR_HELP_INST_CALLED_INVALID, "Help instance called invalid." },
{ HMERR_HELPTABLE_UNDEFINE, "Help table undefined." },
{ HMERR_HELP_INSTANCE_UNDEFINE, "Help instance undefined." },
{ HMERR_HELPITEM_NOT_FOUND, "Help item not found." },
{ HMERR_INVALID_HELPSUBITEM_SIZE, "Invalid help subitem size." },
{ HMERR_HELPSUBITEM_NOT_FOUND, "Help subitem not found." },
{ HMERR_INDEX_NOT_FOUND, "No index in library file." },
{ HMERR_CONTENT_NOT_FOUND, "Table of contents not found." },
{ HMERR_OPEN_LIB_FILE, "Unable to open help library." },
{ HMERR_READ_LIB_FILE, "Unable to read help library." },
{ HMERR_CLOSE_LIB_FILE, "Unable to close help library." },
{ HMERR_INVALID_LIB_FILE, "Help library has invalid format." },
{ HMERR_NO_MEMORY, "Out of memory." },
{ HMERR_ALLOCATE_SEGMENT, "Unable to allocate segment." },
{ HMERR_FREE_MEMORY, "Unable to release memory." },
{ HMERR_PANEL_NOT_FOUND, "Help panel not found." },
{ HMERR_DATABASE_NOT_OPEN, "Help database not open." },
{ 0, "--- Unknown Error ---" }
} ;
DATA *Data = (DATA *) data ;
ULONG ErrorCode = (ULONG) LONGFROMMP ( mp1 ) ;
int Index ;
/***********************************************************************
* Find the error code in the message table. *
***********************************************************************/
Index = 0 ;
while ( HelpErrors[Index].Error
AND ( HelpErrors[Index].Error != ErrorCode ) )
{
Index ++ ;
}
/***********************************************************************
* Display the error message. *
***********************************************************************/
WinMessageBox
(
HWND_DESKTOP,
hwnd,
HelpErrors[Index].Message,
"Help Manager Error",
0,
MB_OK | MB_WARNING
) ;
/***********************************************************************
* Return zero, indicating that the message was processed. *
***********************************************************************/
return ( MRFROMSHORT ( 0 ) ) ;
hwnd = hwnd ; msg = msg ; mp1 = mp1 ; mp2 = mp2 ; data = data ;
}
/************************************************************************
* *
* Process "Extended Help Undefined" notification *
* *
************************************************************************/
static MRESULT APIENTRY ExtHelpUndefined
(
HWND hwnd,
USHORT msg,
MPARAM mp1,
MPARAM mp2,
void *data
)
{
/***********************************************************************
* Local Declarations *
***********************************************************************/
DATA *Data = (DATA *) data ;
/***********************************************************************
* Display the error message. *
***********************************************************************/
WinMessageBox
(
HWND_DESKTOP,
hwnd,
"Extended help undefined.",
"Help Manager Error",
0,
MB_OK | MB_WARNING
) ;
/***********************************************************************
* Return zero, indicating that the message was processed. *
***********************************************************************/
return ( MRFROMSHORT ( 0 ) ) ;
hwnd = hwnd ; msg = msg ; mp1 = mp1 ; mp2 = mp2 ; data = data ;
}
/************************************************************************
* *
* Process "Help Subitem Not Found" notification *
* *
************************************************************************/
static MRESULT APIENTRY HelpSubitemNotFound
(
HWND hwnd,
USHORT msg,
MPARAM mp1,
MPARAM mp2,
void *data
)
{
/***********************************************************************
* Local Declarations *
***********************************************************************/
DATA *Data = (DATA *) data ;
int i ;
BYTE Message [200] ;
PSZ Mode ;
USHORT Subtopic ;
USHORT Topic ;
/***********************************************************************
* Format the error message. *
***********************************************************************/
Topic = (USHORT) SHORT1FROMMP ( mp2 ) ;
Subtopic = (USHORT) SHORT2FROMMP ( mp2 ) ;
i = SHORT1FROMMP ( mp1 ) ;
switch ( i )
{
case HLPM_FRAME:
Mode = "Frame" ;
break ;
case HLPM_MENU:
Mode = "Menu" ;
break ;
case HLPM_WINDOW:
Mode = "Window" ;
break ;
default:
Mode = "Unknown" ;
}
sprintf
(
Message,
"Help subitem not found:\n"
"Mode='%s'\n"
"Topic=%u\n"
"Subtopic=%u",
Mode, Topic, Subtopic
) ;
/***********************************************************************
* Display the error message. *
***********************************************************************/
WinMessageBox
(
HWND_DESKTOP,
hwnd,
Message,
"Help Manager Error",
0,
MB_OK | MB_WARNING
) ;
/***********************************************************************
* Return zero, indicating that the message was processed. *
***********************************************************************/
return ( MRFROMSHORT ( 0 ) ) ;
hwnd = hwnd ; msg = msg ; mp1 = mp1 ; mp2 = mp2 ; data = data ;
}
/************************************************************************
* *
* Get Profile Data *
* *
************************************************************************/
static void GetProfile ( PROFILE *Profile )
{
/***********************************************************************
* Local Declarations *
***********************************************************************/
#define ITEM_BASE_COUNT 5
#define MAX_DRIVES 26
static ITEM Items [ ITEM_BASE_COUNT + MAX_DRIVES ] =
{
{
"ShowMemory", TRUE, "Available memory", 0L,
"Show Memory Free", IDM_SHOW_MEMORY,
ComputeFreeMemory, 0, 1024, 'K'
},
{
"ShowSwapsize", TRUE, "Swap-file size", 0L,
"Show Swapfile Size", IDM_SHOW_SWAPSIZE,
ComputeSwapSize, 0, 1024, 'K'
},
{
"ShowSwapfree", TRUE, "Available swap space", 0L,
"Show Swap Space Free", IDM_SHOW_SWAPFREE,
ComputeSwapFree, 0, 1024, 'K'
},
{
"ShowSpoolSize",TRUE, "Spool-file size", 0L,
"Show Spool Size", IDM_SHOW_SPOOLSIZE,
ComputeSpoolSize, 0, 1024, 'K'
},
{
"ShowCpuLoad", TRUE, "CPU Load", 0L,
"Show CPU Load", IDM_SHOW_CPULOAD,
ComputeCpuLoad, 0, 0, '%'
}
} ;
int Count ;
USHORT Drive ;
ULONG Drives ;
int i ;
ULONG Size ;
/***********************************************************************
* Add items for each drive on the system. *
***********************************************************************/
Count = ITEM_BASE_COUNT ;
DosQCurDisk ( &Drive, &Drives ) ;
for ( Drive=1; Drive<26; Drive++ )
{
if ( Drives & 1 )
{
USHORT Action ;
USHORT Handle ;
BYTE Path [3] ;
Path[0] = (BYTE) ( Drive + 'A' - 1 ) ;
Path[1] = ':' ;
Path[2] = 0 ;
if ( !DosOpen ( Path, &Handle, &Action, 0, 0, FILE_OPEN,
OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE |
OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR, 0 ) )
{
BIOSPARAMETERBLOCK BiosParms ;
BYTE Command = 0 ;
if ( !DosDevIOCtl ( &BiosParms, &Command, 0x0063, 0x0008, Handle ) )
{
if ( BiosParms.fsDeviceAttr & 1 )
{
char Name [40] ;
char Label [40] ;
char MenuOption [40] ;
sprintf ( Name, "ShowDrive%c:", Drive+'A'-1 ) ;
sprintf ( Label, "Drive %c: free space", Drive+'A'-1 ) ;
sprintf ( MenuOption, "Show %c: Free Space", Drive+'A'-1 ) ;
Items[Count].Name = malloc ( strlen(Name)+1 ) ;
strcpy ( Items[Count].Name, Name ) ;
Items[Count].Flag = TRUE ;
Items[Count].Label = malloc ( strlen(Label)+1 ) ;
strcpy ( Items[Count].Label, Label ) ;
Items[Count].Value = 0L ;
Items[Count].MenuOption = malloc ( strlen(MenuOption)+1 ) ;
strcpy ( Items[Count].MenuOption, MenuOption ) ;
Items[Count].MenuId = IDM_SHOW_DRIVE_FREE + Drive ;
Items[Count].NewValue = ComputeDriveFree ;
Items[Count].Parm = Drive ;
Items[Count].Divisor = 1024 ;
Items[Count].Suffix = 'K' ;
Count ++ ;
}
}
DosClose ( Handle ) ;
}
}
Drives >>= 1 ;
}
/***********************************************************************
* Save pointer to fixed configuration information. *
***********************************************************************/
Profile->Items = Items ;
Profile->ItemCount = Count ;
/***********************************************************************
* Get the window's current size and position. *
***********************************************************************/
memset ( &Profile->Position, 0, sizeof(Profile->Position) ) ;
Profile->fPosition = FALSE ;
if
(
PrfQueryProfileSize ( HINI_PROFILE, PROGRAM_NAME, "Position", &Size )
AND
( Size == sizeof(Profile->Position) )
AND
PrfQueryProfileData ( HINI_PROFILE, PROGRAM_NAME, "Position", &Profile->Position, &Size )
)
{
Profile->fPosition = TRUE ;
}
/***********************************************************************
* Get the program options. *
***********************************************************************/
Profile->HideControls = FALSE ;
if
(
PrfQueryProfileSize ( HINI_PROFILE, PROGRAM_NAME, "HideControls", &Size )
AND
( Size == sizeof(Profile->HideControls) )
AND
PrfQueryProfileData ( HINI_PROFILE, PROGRAM_NAME, "HideControls", &Profile->HideControls, &Size )
)
{
;
}
/***********************************************************************
* Get the item options. *
***********************************************************************/
for ( i=0; i<Profile->ItemCount; i++ )
{
ITEM *Item = & Profile->Items [i] ;
Item->Flag = TRUE ;
if
(
PrfQueryProfileSize ( HINI_PROFILE, PROGRAM_NAME, Item->Name, &Size )
AND
( Size == sizeof(Item->Flag) )
AND
PrfQueryProfileData ( HINI_PROFILE, PROGRAM_NAME, Item->Name, &Item->Flag, &Size )
)
{
;
}
}
/***********************************************************************
* Get the presentation parameters. *
***********************************************************************/
strcpy ( Profile->FontNameSize, "" ) ;
Profile->fFontNameSize = FALSE ;
if
(
PrfQueryProfileSize ( HINI_PROFILE, PROGRAM_NAME, "FontNameSize", &Size )
AND
( Size == sizeof(Profile->FontNameSize) )
AND
PrfQueryProfileData ( HINI_PROFILE, PROGRAM_NAME, "FontNameSize", &Profile->FontNameSize, &Size )
)
{
Profile->fFontNameSize = TRUE ;
}
Profile->BackColor = WinQuerySysColor ( HWND_DESKTOP, SYSCLR_WINDOW, 0L ) ;
Profile->fBackColor = FALSE ;
if
(
PrfQueryProfileSize ( HINI_PROFILE, PROGRAM_NAME, "BackgroundColor", &Size )
AND
( Size == sizeof(Profile->BackColor) )
AND
PrfQueryProfileData ( HINI_PROFILE, PROGRAM_NAME, "BackgroundColor", &Profile->BackColor, &Size )
)
{
Profile->fBackColor = TRUE ;
}
Profile->TextColor = WinQuerySysColor ( HWND_DESKTOP, SYSCLR_OUTPUTTEXT, 0L ) ;
Profile->fTextColor = FALSE ;
if
(
PrfQueryProfileSize ( HINI_PROFILE, PROGRAM_NAME, "ForegroundColor", &Size )
AND
( Size == sizeof(Profile->TextColor) )
AND
PrfQueryProfileData ( HINI_PROFILE, PROGRAM_NAME, "ForegroundColor", &Profile->TextColor, &Size )
)
{
Profile->fTextColor = TRUE ;
}
}
/************************************************************************
* *
* Put Profile Data *
* *
************************************************************************/
static void PutProfile ( PROFILE *Profile )
{
/***********************************************************************
* Local Declarations *
***********************************************************************/
int i ;
/***********************************************************************
* Save the window's current size and position. *
***********************************************************************/
PrfWriteProfileData
(
HINI_USERPROFILE,
PROGRAM_NAME,
"Position",
&Profile->Position,
(ULONG)sizeof(Profile->Position)
) ;
/***********************************************************************
* Save the program options. *
***********************************************************************/
PrfWriteProfileData
(
HINI_USERPROFILE,
PROGRAM_NAME,
"HideControls",
&Profile->HideControls,
(ULONG)sizeof(Profile->HideControls)
) ;
/***********************************************************************
* Save the item options. *
***********************************************************************/
for ( i=0; i<Profile->ItemCount; i++ )
{
ITEM *Item = & Profile->Items [i] ;
PrfWriteProfileData
(
HINI_USERPROFILE,
PROGRAM_NAME,
Item->Name,
&Item->Flag,
(ULONG)sizeof(Item->Flag)
) ;
}
/***********************************************************************
* Save the presentation parameters. *
***********************************************************************/
if ( Profile->fFontNameSize )
{
PrfWriteProfileData
(
HINI_USERPROFILE,
PROGRAM_NAME,
"FontNameSize",
Profile->FontNameSize,
(ULONG)sizeof(Profile->FontNameSize)
) ;
}
if ( Profile->fBackColor )
{
PrfWriteProfileData
(
HINI_USERPROFILE,
PROGRAM_NAME,
"BackgroundColor",
&Profile->BackColor,
(ULONG)sizeof(Profile->BackColor)
) ;
}
if ( Profile->fTextColor )
{
PrfWriteProfileData
(
HINI_USERPROFILE,
PROGRAM_NAME,
"ForegroundColor",
&Profile->TextColor,
(ULONG)sizeof(Profile->TextColor)
) ;
}
}
/************************************************************************
* *
* Scan CONFIG.SYS for a keyword. Return the value. *
* *
************************************************************************/
static char *ScanSystemConfig ( char *Keyword )
{
/***********************************************************************
* Local Declarations *
***********************************************************************/
static char Buffer [500] ;
FILE *File ;
SEL GlobalSelector ;
SEL LocalSelector ;
char Path [_MAX_PATH] ;
GINFOSEG FAR *pGlobalInfoSeg ;
/***********************************************************************
* Get the boot drive number from the global information segment. *
***********************************************************************/
DosGetInfoSeg ( &GlobalSelector, &LocalSelector ) ;
pGlobalInfoSeg = MAKEPGINFOSEG ( GlobalSelector ) ;
/***********************************************************************
* Build the CONFIG.SYS path. *
***********************************************************************/
Path[0] = (char) ( pGlobalInfoSeg->bootdrive + 'A' - 1 ) ;
Path[1] = 0 ;
strcat ( Path, ":\\CONFIG.SYS" ) ;
/***********************************************************************
* Open CONFIG.SYS for reading. *
***********************************************************************/
File = fopen ( Path, "rt" ) ;
if ( NOT File )
{
return ( NULL ) ;
}
/***********************************************************************
* While there're more lines in CONFIG.SYS, read a line and check it. *
***********************************************************************/
while ( fgets ( Buffer, sizeof(Buffer), File ) )
{
/*********************************************************************
* Clean any trailing newline character from the input string. *
*********************************************************************/
if ( Buffer[strlen(Buffer)-1] == '\n' )
{
Buffer[strlen(Buffer)-1] = 0 ;
}
/*********************************************************************
* If keyword starts the line, we've found the line we want. Close *
* the file and return a pointer to the parameter text. *
*********************************************************************/
if ( NOT strnicmp ( Buffer, Keyword, strlen(Keyword) )
AND ( Buffer[strlen(Keyword)] == '=' ) )
{
fclose ( File ) ;
return ( Buffer + strlen(Keyword) + 1 ) ;
}
}
/***********************************************************************
* Close the file. We haven't found the line we wanted. *
***********************************************************************/
fclose ( File ) ;
return ( NULL ) ;
}
/************************************************************************
* *
* Resize Client Window *
* *
************************************************************************/
static void ResizeWindow ( HWND hwnd, PROFILE *Profile )
{
/***********************************************************************
* Local Declarations *
***********************************************************************/
SHORT Count ;
SHORT fHadToHide = FALSE ;
SHORT fHadToRestore = FALSE ;
LONG Height ;
HPS hPS ;
HWND hwndFrame ;
short i ;
RECTL Rectangle ;
char Text [100] ;
LONG Widest ;
/***********************************************************************
* If the window is visible and minimized, restore it invisibly. *
***********************************************************************/
hwndFrame = WinQueryWindow ( hwnd, QW_PARENT, FALSE ) ;
if ( Profile->Position.fs & SWP_MINIMIZE )
{
if ( WinIsWindowVisible ( hwndFrame ) )
{
WinShowWindow ( hwndFrame, FALSE ) ;
fHadToHide = TRUE ;
}
WinSetWindowPos ( hwndFrame, NULL, 0, 0, 0, 0, SWP_RESTORE ) ;
fHadToRestore = TRUE ;
}
/***********************************************************************
* Determine how many items are to be displayed. *
***********************************************************************/
hPS = WinGetPS ( hwnd ) ;
Count = 0 ;
Widest = 0 ;
Height = 0 ;
for ( i=0; i<Profile->ItemCount; i++ )
{
ITEM *Item = & Profile->Items [i] ;
if ( Item->Flag )
{
Count ++ ;
sprintf ( Text, "%s 1,234,567K", Item->Label ) ;
WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
WinDrawText ( hPS, strlen(Text), Text,
&Rectangle, 0L, 0L, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
Widest = max ( Widest, (Rectangle.xRight-Rectangle.xLeft) ) ;
Height += Rectangle.yTop - Rectangle.yBottom ;
}
}
WinReleasePS ( hPS ) ;
/***********************************************************************
* Get the window's current size & position. *
***********************************************************************/
WinQueryWindowRect ( hwndFrame, &Rectangle ) ;
WinCalcFrameRect ( hwndFrame, &Rectangle, TRUE ) ;
/***********************************************************************
* Adjust the window's width & height. *
***********************************************************************/
Rectangle.xRight = Rectangle.xLeft + Widest ;
Rectangle.yTop = Rectangle.yBottom + Height ;
/***********************************************************************
* Compute new frame size and apply it. *
***********************************************************************/
WinCalcFrameRect ( hwndFrame, &Rectangle, FALSE ) ;
WinSetWindowPos ( hwndFrame, NULL, 0, 0,
(SHORT) (Rectangle.xRight-Rectangle.xLeft),
(SHORT) (Rectangle.yTop-Rectangle.yBottom),
SWP_SIZE ) ;
/***********************************************************************
* Return the window to its original state. *
***********************************************************************/
if ( fHadToRestore )
{
WinSetWindowPos ( hwndFrame, NULL,
Profile->Position.x, Profile->Position.y,
Profile->Position.cx, Profile->Position.cy,
SWP_MOVE | SWP_SIZE | SWP_MINIMIZE ) ;
}
if ( fHadToHide )
{
WinShowWindow ( hwndFrame, TRUE ) ;
}
/***********************************************************************
* Invalidate the window so that it gets repainted. *
***********************************************************************/
WinInvalidateRect ( hwnd, NULL, TRUE ) ;
}
/************************************************************************
* *
* Hide Window Controls *
* *
************************************************************************/
static void HideControls
(
BOOL fHide,
HWND hwndFrame,
HWND hwndSysMenu,
HWND hwndTitleBar,
HWND hwndMinMax
)
{
/***********************************************************************
* Local Declarations *
***********************************************************************/
SWP Position ;
RECTL Rectangle ;
/***********************************************************************
* Determine client window and location. *
***********************************************************************/
WinQueryWindowPos ( hwndFrame, &Position ) ;
Rectangle.xLeft = Position.x ;
Rectangle.xRight = Position.x + Position.cx ;
Rectangle.yBottom = Position.y ;
Rectangle.yTop = Position.y + Position.cy ;
WinCalcFrameRect ( hwndFrame, &Rectangle, TRUE ) ;
/***********************************************************************
* Hide or reveal the controls windows by changing their parentage. *
***********************************************************************/
if ( fHide )
{
WinSetParent ( hwndSysMenu, HWND_OBJECT, FALSE ) ;
WinSetParent ( hwndTitleBar, HWND_OBJECT, FALSE ) ;
WinSetParent ( hwndMinMax, HWND_OBJECT, FALSE ) ;
}
else
{
WinSetParent ( hwndSysMenu, hwndFrame, TRUE ) ;
WinSetParent ( hwndTitleBar, hwndFrame, TRUE ) ;
WinSetParent ( hwndMinMax, hwndFrame, TRUE ) ;
}
/***********************************************************************
* Tell the frame that things have changed. Let it update the window. *
***********************************************************************/
WinSendMsg ( hwndFrame, WM_UPDATEFRAME,
MPFROMSHORT ( FCF_TITLEBAR | FCF_SYSMENU | FCF_MINBUTTON ), 0L ) ;
/***********************************************************************
* Reposition the frame around the client window, which is left be. *
***********************************************************************/
WinCalcFrameRect ( hwndFrame, &Rectangle, FALSE ) ;
WinSetWindowPos ( hwndFrame, NULL,
(SHORT) Rectangle.xLeft, (SHORT) Rectangle.yBottom,
(SHORT) (Rectangle.xRight-Rectangle.xLeft),
(SHORT) (Rectangle.yTop-Rectangle.yBottom),
SWP_SIZE | SWP_MOVE ) ;
}
/************************************************************************
* *
* Display Debug Message *
* *
************************************************************************/
static void Debug ( HWND hwnd, char *Message, ... )
{
va_list Marker ;
char Text [500] ;
va_start ( Marker, Message ) ;
vsprintf ( Text, Message, Marker ) ;
va_end ( Marker ) ;
WinMessageBox ( HWND_DESKTOP, hwnd, Text, "Debug", 0, MB_ENTER ) ;
}
/************************************************************************
* *
* Calibrate the CPU Load Meter. *
* *
************************************************************************/
static ULONG CalibrateLoad ( void )
{
CALIBRATION_PARMS Parms ;
PIDINFO PidInfo ;
TID tid ;
DosGetPID ( &PidInfo ) ;
DosSetPrty ( PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, PidInfo.tid ) ;
tid = _beginthread ( CalibrationThread, NULL, 4000, &Parms ) ;
DosSleep ( 1000L ) ;
DosSuspendThread ( tid ) ;
DosSetPrty ( PRTYS_THREAD, PRTYC_REGULAR, 0, PidInfo.tid ) ;
return ( Parms.Count ) ;
}
/************************************************************************
* *
* Thread to collect CPU loading statistics. *
* *
************************************************************************/
static void _cdecl _far TimingThread ( TIMING_PARMS *Parms )
{
PIDINFO PidInfo ;
DosGetPID ( &PidInfo ) ;
DosSetPrty ( PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, PidInfo.tid ) ;
*Parms->Count = 0 ;
while ( TRUE )
{
DosSleep ( 1000L ) ;
WinPostMsg ( Parms->hwndClient, WM_SEM1,
MPFROMLONG ( *Parms->Count ), NULL ) ;
*Parms->Count = 0 ;
}
}
/************************************************************************
* *
* Thread to count unused CPU cycles. *
* *
************************************************************************/
static void _cdecl _far CountingThread ( COUNTING_PARMS *Parms )
{
PIDINFO PidInfo ;
DosGetPID ( &PidInfo ) ;
DosSetPrty ( PRTYS_THREAD, PRTYC_IDLETIME, PRTYD_MINIMUM, PidInfo.tid ) ;
while ( TRUE )
{
(*Parms->Count) ++ ;
}
}
/************************************************************************
* *
* Thread to count CPU cycles per second. *
* *
************************************************************************/
static void _cdecl _far CalibrationThread ( CALIBRATION_PARMS *Parms )
{
PIDINFO PidInfo ;
DosGetPID ( &PidInfo ) ;
DosSetPrty ( PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM-1, PidInfo.tid ) ;
Parms->Count = 0 ;
while ( TRUE )
{
Parms->Count ++ ;
}
}
/************************************************************************
* *
* Update Window *
* *
************************************************************************/
static void UpdateWindow ( HWND hwnd, DATA *Data, BOOL All )
{
/***********************************************************************
* Declarations *
***********************************************************************/
int Count ;
HPS hPS ;
short i ;
RECTL Rectangle ;
char Text [40] ;
/***********************************************************************
* Determine how many items are to be displayed. *
***********************************************************************/
Count = 0 ;
for ( i=0; i<Data->Profile.ItemCount; i++ )
{
if ( Data->Profile.Items[i].Flag )
{
Count ++ ;
}
}
/***********************************************************************
* Get presentation space and make it use RGB colors. *
***********************************************************************/
hPS = WinGetPS ( hwnd ) ;
GpiCreateLogColorTable ( hPS, LCOL_RESET, LCOLF_RGB, 0L, 0L, NULL ) ;
/***********************************************************************
* Get the window's size and determine the initial position. *
***********************************************************************/
WinQueryWindowRect ( hwnd, &Rectangle ) ;
Rectangle.xLeft += Data->FontMetrics.lAveCharWidth / 2 ;
Rectangle.xRight -= Data->FontMetrics.lAveCharWidth / 2 ;
Rectangle.yBottom = Data->FontMetrics.lMaxBaselineExt * ( Count - 1 ) ;
Rectangle.yTop = Rectangle.yBottom + Data->FontMetrics.lMaxBaselineExt - 1 ;
/***********************************************************************
* Review all items. Display those changed, or all. *
***********************************************************************/
for ( i=0; i<Data->Profile.ItemCount; i++ )
{
ITEM *Item = & Data->Profile.Items [i] ;
ULONG NewValue ;
if ( Item->Flag )
{
NewValue = Item->NewValue ( Data, Item->Parm ) ;
if ( All OR ( NewValue != Item->Value ) )
{
memset ( Text, 0, sizeof(Text) ) ;
if ( Item->Divisor )
{
if ( NewValue < Item->Divisor * 1000 )
sprintf ( Text, "%lu", NewValue ) ;
else
sprintf ( Text, "%lu", (NewValue+Item->Divisor/2)/Item->Divisor ) ;
}
else
{
sprintf ( Text, "%lu", NewValue ) ;
}
{
PCHAR p1, p2 ;
CHAR Work[100] ;
p1 = Text ;
p2 = Work ;
while ( *p1 )
{
*p2 = *p1 ;
p1 ++ ;
p2 ++ ;
if ( *p1 )
{
if ( strlen(p1) % 3 == 0 )
{
*p2 = ',' ;
p2 ++ ;
}
}
}
*p2 = 0 ;
strcpy ( Text, Work ) ;
}
if ( Item->Divisor )
{
if ( NewValue < Item->Divisor * 1000 )
Text[strlen(Text)] = ' ' ;
else
Text[strlen(Text)] = Item->Suffix ;
}
else
{
Text[strlen(Text)] = Item->Suffix ;
}
WinDrawText ( hPS, strlen(Text), Text, &Rectangle,
Data->Profile.TextColor, Data->Profile.BackColor,
DT_RIGHT | DT_BOTTOM | DT_ERASERECT ) ;
strcpy ( Text, Item->Label ) ;
WinDrawText ( hPS, strlen(Text), Text, &Rectangle,
Data->Profile.TextColor, Data->Profile.BackColor,
DT_LEFT | DT_BOTTOM ) ;
Item->Value = NewValue ;
}
Rectangle.yBottom -= Data->FontMetrics.lMaxBaselineExt ;
Rectangle.yTop -= Data->FontMetrics.lMaxBaselineExt ;
}
}
/***********************************************************************
* Release the presentation space and return. *
***********************************************************************/
WinReleasePS ( hPS ) ;
}
/************************************************************************
* *
* Compute Available Memory *
* *
************************************************************************/
static ULONG ComputeFreeMemory ( DATA *Data, USHORT Dummy )
{
ULONG MemFree ;
DosMemAvail ( &MemFree ) ;
return ( MemFree ) ;
}
/************************************************************************
* *
* Compute Swap-File Size *
* *
************************************************************************/
static ULONG ComputeSwapSize ( DATA *Data, USHORT Dummy )
{
/***********************************************************************
* Declarations *
***********************************************************************/
char Path [_MAX_PATH+1] ;
struct stat Status ;
ULONG SwapSize ;
/***********************************************************************
* Find the swap file and find its size. *
***********************************************************************/
strcpy ( Path, Data->SwapPath ) ;
if ( Path[strlen(Path)-1] != '\\' )
{
strcat ( Path, "\\" ) ;
}
strcat ( Path, "SWAPPER.DAT" ) ;
SwapSize = 0 ;
if ( stat ( Path, &Status ) == 0 )
{
SwapSize = Status.st_size ;
}
return ( SwapSize ) ;
}
/************************************************************************
* *
* Compute Available Swap Space *
* *
************************************************************************/
static ULONG ComputeSwapFree ( DATA *Data, USHORT Dummy )
{
/***********************************************************************
* Declarations *
***********************************************************************/
FSALLOCATE Allocation ;
char Path [_MAX_PATH+1] ;
ULONG SwapFree ;
/***********************************************************************
* Find the swap file and find its size. *
***********************************************************************/
strcpy ( Path, Data->SwapPath ) ;
strcat ( Path, "\\SWAPPER.DAT" ) ;
/***********************************************************************
* Compute swap device free space. *
***********************************************************************/
SwapFree = 0 ;
if ( Path[0] )
{
DosQFSInfo ( Path[0]-'A'+1, FSIL_ALLOC,
(PBYTE)&Allocation, sizeof(Allocation) ) ;
SwapFree = Allocation.cUnitAvail*Allocation.cSectorUnit*Allocation.cbSector ;
}
/***********************************************************************
* Return swap device's free space, less the minimum free space. *
***********************************************************************/
if ( SwapFree < (ULONG)Data->MinFree*1024L )
return ( 0L ) ;
else
return ( SwapFree - (ULONG)Data->MinFree * 1024L ) ;
}
/************************************************************************
* *
* Compute Spool-file Size *
* *
************************************************************************/
static ULONG ComputeSpoolSize ( DATA *Data, USHORT Dummy )
{
USHORT Count ;
FILEFINDBUF *Found ;
HDIR hDir = HDIR_CREATE ;
BYTE *Path ;
USHORT PathSize ;
ULONG TotalSize = 0 ;
DosQSysInfo ( 0, (BYTE*)&PathSize, sizeof(PathSize) ) ;
Path = malloc ( PathSize ) ;
if ( Path == NULL )
{
return ( 0 ) ;
}
Found = malloc ( PathSize + sizeof(FILEFINDBUF) ) ;
if ( Found == NULL )
{
free ( Path ) ;
return ( 0 ) ;
}
strcpy ( Path, Data->SpoolPath ) ;
strcat ( Path, "\\*.*" ) ;
Count = 1 ;
if ( !DosFindFirst ( Path, &hDir,
FILE_NORMAL | FILE_READONLY | FILE_DIRECTORY | FILE_ARCHIVED,
Found, PathSize+sizeof(FILEFINDBUF), &Count, 0L ) )
{
do
{
if ( !strcmp ( Found->achName, "." )
OR !strcmp ( Found->achName, ".." ) )
{
continue ;
}
if ( Found->attrFile & FILE_DIRECTORY )
{
HDIR hDir = HDIR_CREATE ;
strcpy ( Path, Data->SpoolPath ) ;
strcat ( Path, "\\" ) ;
strcat ( Path, Found->achName ) ;
strcat ( Path, "\\*.*" ) ;
Count = 1 ;
if ( !DosFindFirst ( Path, &hDir,
FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED,
Found, PathSize+sizeof(FILEFINDBUF), &Count, 0L ) )
{
do
{
TotalSize += Found->cbFileAlloc ;
}
while ( !DosFindNext ( hDir, Found, PathSize+sizeof(FILEFINDBUF), &Count ) ) ;
DosFindClose ( hDir ) ;
Count = 1 ;
}
}
else
{
TotalSize += Found->cbFileAlloc ;
}
}
while ( !DosFindNext ( hDir, Found, PathSize+sizeof(FILEFINDBUF), &Count ) ) ;
DosFindClose ( hDir ) ;
}
free ( Path ) ;
free ( Found ) ;
return ( TotalSize ) ;
}
/************************************************************************
* *
* Compute CPU Load *
* *
************************************************************************/
static ULONG ComputeCpuLoad ( DATA *Data, USHORT Dummy )
{
return ( Data->NewLoad ) ;
}
/************************************************************************
* *
* Compute Drive Free Space *
* *
************************************************************************/
static ULONG ComputeDriveFree ( DATA *Data, USHORT Drive )
{
FSALLOCATE Allocation ;
DosQFSInfo ( Drive, FSIL_ALLOC,
(PBYTE)&Allocation, sizeof(Allocation) ) ;
return ( Allocation.cUnitAvail*Allocation.cSectorUnit*Allocation.cbSector ) ;
}